package io.github.echarts.model.theme;

import io.github.echarts.option.style.LineStyle;
import io.github.echarts.option.style.TextStyle;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 延迟计算的主题提供者
 * <p>
 * 提供延迟计算和缓存机制的主题提供者，用于优化性能。
 * 对于计算成本较高的主题相关操作，可以使用此类来进行懒加载和缓存。
 * </p>
 */
public class LazyThemeProvider {
    
    /**
     * 单例实例
     */
    private static final LazyThemeProvider INSTANCE = new LazyThemeProvider();
    
    /**
     * 主题缓存
     */
    private final Map<String, Theme> themeCache = new ConcurrentHashMap<>();
    
    /**
     * 组件主题缓存
     */
    private final Map<String, Object> componentThemeCache = new ConcurrentHashMap<>();
    
    /**
     * 主题样式缓存
     */
    private final Map<String, Object> styleCache = new ConcurrentHashMap<>();
    
    /**
     * 私有构造函数
     */
    private LazyThemeProvider() {
        // 私有构造函数，防止外部实例化
    }
    
    /**
     * 获取单例实例
     * 
     * @return LazyThemeProvider实例
     */
    public static LazyThemeProvider getInstance() {
        return INSTANCE;
    }
    
    /**
     * 获取主题，如果不存在则延迟创建
     * 
     * @param themeName 主题名称
     * @param themeFactory 主题创建工厂
     * @return 主题对象
     */
    public Theme getOrCreateTheme(String themeName, Supplier<Theme> themeFactory) {
        return themeCache.computeIfAbsent(themeName, name -> themeFactory.get());
    }
    
    /**
     * 获取组件主题，如果不存在则延迟创建
     * 
     * @param <T> 组件主题类型
     * @param theme 主题
     * @param componentType 组件类型
     * @param keyGenerator 缓存键生成器
     * @param themeFactory 组件主题创建工厂
     * @return 组件主题对象
     */
    @SuppressWarnings("unchecked")
    public <T> T getOrCreateComponentTheme(Theme theme, String componentType, 
                                        Function<String, String> keyGenerator,
                                        Function<Theme, T> themeFactory) {
        String cacheKey = keyGenerator.apply(theme.getName() + "-" + componentType);
        return (T) componentThemeCache.computeIfAbsent(cacheKey, k -> themeFactory.apply(theme));
    }
    
    /**
     * 获取文本样式，如果不存在则延迟创建
     * 
     * @param theme 主题
     * @param styleType 样式类型
     * @param keyGenerator 缓存键生成器
     * @return 文本样式对象
     */
    public TextStyle getOrCreateTextStyle(Theme theme, String styleType, Function<String, String> keyGenerator) {
        String cacheKey = keyGenerator.apply(theme.getName() + "-text-" + styleType);
        return (TextStyle) styleCache.computeIfAbsent(cacheKey, k -> theme.getTextStyle());
    }
    
    /**
     * 获取线条样式，如果不存在则延迟创建
     * 
     * @param theme 主题
     * @param styleType 样式类型
     * @param keyGenerator 缓存键生成器
     * @return 线条样式对象
     */
    public LineStyle getOrCreateLineStyle(Theme theme, String styleType, Function<String, String> keyGenerator) {
        String cacheKey = keyGenerator.apply(theme.getName() + "-line-" + styleType);
        return (LineStyle) styleCache.computeIfAbsent(cacheKey, k -> theme.getLineStyle());
    }
    
    /**
     * 清除所有缓存
     */
    public void clearCache() {
        themeCache.clear();
        componentThemeCache.clear();
        styleCache.clear();
    }
    
    /**
     * 清除特定主题的缓存
     * 
     * @param themeName 主题名称
     */
    public void clearThemeCache(String themeName) {
        themeCache.remove(themeName);
        
        // 清除与此主题相关的组件主题和样式缓存
        String prefix = themeName + "-";
        componentThemeCache.keySet().removeIf(key -> key.startsWith(prefix));
        styleCache.keySet().removeIf(key -> key.startsWith(prefix));
    }
    
    /**
     * 获取缓存大小
     * 
     * @return 缓存大小
     */
    public int getCacheSize() {
        return themeCache.size() + componentThemeCache.size() + styleCache.size();
    }
} 